/*
 * $Id: arp.c,v 1.7 2006-06-02 16:21:58 bacon Exp $
 */

#include <xp/net/arp.h>
#include <xp/bas/memory.h>
#include <xp/bas/endian.h>

#if defined(__FreeBSD__)
	#include <net/ethernet.h>
#elif defined(__linux)
	#include <netpacket/packet.h>
	#include <net/ethernet.h>
#elif defined(sun)||defined(__sun)
	#include <sys/ethernet.h>
#else
	#error not supported	
#endif

xp_arp_t* xp_arp_open (xp_arp_t* arp)
{
	if (arp == XP_NULL) {
		arp = (xp_arp_t*) xp_malloc (xp_sizeof(xp_arp_t));
		if (arp == XP_NULL) return XP_NULL;
		arp->__dynamic = xp_true;
	}
	else arp->__dynamic = xp_false;

#if defined(__FreeBSD__)
	/* TODO: is this correct??? */
	if (xp_sck_open (&arp->sck, 
		PF_LINK, SOCK_RAW, xp_hton16(ETHERTYPE_ARP)) == XP_NULL) {
#elif defined(sun)||defined(__sun)
	/* TODO: i don't think this is correct */
	if (xp_sck_open (&arp->sck, 
		PF_INET, SOCK_RAW, xp_hton16(ETHERTYPE_ARP)) == XP_NULL) {
#else
	if (xp_sck_open (&arp->sck, 
		PF_PACKET, SOCK_RAW, xp_hton16(ETH_P_ARP)) == XP_NULL) {
#endif
		if (arp->__dynamic) xp_free (arp);
		return XP_NULL;	
	}

	return arp;
}

int xp_arp_close (xp_arp_t* arp)
{
	if (xp_sck_close(&arp->sck) == -1) return -1;
	if (arp->__dynamic) xp_free (arp);
	return 0;
}

#if 0
int xp_arp_send (xp_arp_t* arp)
{
	sturct arphdr ah;

	//ah->ar_hrd
	ah->ar_hrd = xp_hton16(ARPHRD_ETHER);
	ah->ar_pro = xp_hton16(ETH_P_IP);
	ah->ar_hln = ME->sll_halen;
	ah->ar_pln = 4;
	ah->ar_op = xp_hton16(ARPOP_REPLY): xp_hton16(ARPOP_REQUEST);
}

#endif

int xp_arp_ping4 (xp_arp_t* arp, const xp_char_t* ifce, 
	xp_uint32_t* ip, xp_byte_t mac[XP_ETHER_LEN])
{
	return -1;
}
